package com.skywork.service;

import java.util.List;

import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.skywork.dao.AccessTokenMapper;
import com.skywork.domain.AccessToken;
import com.skywork.domain.Channel;
import com.skywork.domain.base.ActiveFlag;
import com.skywork.service.base.BaseService;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

@Service
@CacheConfig(cacheNames = "accessToken")
public class AccessTokenService extends BaseService<AccessToken> {

	@Autowired
	private AccessTokenMapper accessTokenMapper;

	@Autowired
	private EhCahceService cacheService;


	@CacheEvict(cacheNames = "accessTokenByChannelId", key = "#p0")
	public void removeDbTokenByChannelId(String channelId) {

	}

	@Transactional(rollbackFor = { Exception.class })
	public AccessToken getAccessTokenByChannelId(Channel channel) {
		AccessToken at = new AccessToken();
		at.setActiveFlag(ActiveFlag.ACTIVE);
		at.setChannelId(channel.getId());

		List<AccessToken> accessTokenList = select(at);
		for (int i = 0; i < accessTokenList.size(); i++) {
			cacheService.remove("accessToken", accessTokenList.get(i).getToken());
		}
		accessTokenMapper.updateInActiveByChannelId(channel.getId());

		AccessToken accessToken = new AccessToken(channel.getId(), RandomStringUtils.randomAlphanumeric(126), channel.getTokenExpiresIn());
		insertUseGeneratedKeys(accessToken);
		cacheService.setCache("accessTokenByChannelId", channel.getId() + "", accessToken, accessToken.getExpiresIn());
		cacheService.setCache("accessToken", accessToken.getToken(), accessToken, accessToken.getExpiresIn());
		return accessToken;
	}

	// @Cacheable(cacheNames = "accessToken", key = "#p0")
	public AccessToken findByToken(String token) {
		// PageHelper.startPage(1, 10);
		AccessToken accessToken = null;
		try {
			AccessToken accessTokenCache = (AccessToken) cacheService.get("accessToken", token);
			if (accessTokenCache != null && accessTokenCache.isAvailable()) {
				AccessToken accessTokenByChannel = (AccessToken) cacheService.get("accessTokenByChannelId", accessTokenCache.getChannelId() + "");
				if (accessTokenByChannel != null && accessTokenByChannel.isAvailable()) {
					if (accessTokenCache.getToken().equals(accessTokenByChannel.getToken())){
						accessToken = accessTokenCache;
					}
				}
			}
		} catch (Exception e) {
			LOGGER.error(e.toString(), e);
		}
		if (accessToken == null) {
			Example example = new Example(AccessToken.class);
			Criteria criteria = example.createCriteria();
			criteria.andEqualTo("token", token);
			criteria.andEqualTo("activeFlag", ActiveFlag.ACTIVE.getValue());
			List<AccessToken> accessTokenList = accessTokenMapper.selectByExample(example);
			if (accessTokenList != null) {
				if (accessTokenList.size() == 1 && accessTokenList.get(0).isAvailable()) {
					accessToken = accessTokenList.get(0);
					cacheService.setCache("accessToken", accessToken.getToken(), accessToken, accessToken.getExpiresIn());
				}
			}
		}
		return accessToken;
	}

}
